#ifndef __HERM_UTILS_SINGLETON_H__
#define __HERM_UTILS_SINGLETON_H__

namespace herm{

/**
 * @brief Singleton.
 */
template <class T>
class Singleton
{
public:
	virtual ~Singleton()
	{
	}

	static T* Instance()
	{
		if (!m_instance)
			m_instance = new T; 

		return m_instance;
	} 
	
	static void Destroy()
	{
		delete m_instance;
		m_instance = nullptr;
	}

private:
	typedef T InstanceType;
	static T* m_instance;
}; 

template <class T> 
typename Singleton<T>::InstanceType* Singleton<T>::m_instance = nullptr;


template <class T>
class SingletonHolder
{
public:
	static void SetInstance(T* instance)
	{
		m_instance = instance;
	}

	static T* Instance()
	{
		return m_instance;
	} 

	static void Destroy()
	{
		delete m_instance;
		m_instance = nullptr;
	}
private:
	SingletonHolder(){}
	~SingletonHolder(){}
	SingletonHolder(const SingletonHolder<T>&) {}
	SingletonHolder<T>& operator=(const SingletonHolder<T>&){}

private:
	typedef T InstanceType;
	static T* m_instance;
}; 

template <class T> 
typename SingletonHolder<T>::InstanceType* SingletonHolder<T>::m_instance = nullptr;

}

#endif
